#include <pthread.h>
#include <stdio.h>
#include <QX11EmbedWidget>
#include <QVBoxLayout>
#include <QApplication>
#include <QClipboard>
#include <QTranslator>
#include <QLocale>
#include <QLibraryInfo>
#include <QVariant>
#include <QPalette>
#include <QColor>
#include <QFont>
#include <gdk/gdkx.h>
#include <gtk/gtkstyle.h>
#include <gtk/gtkwidget.h>
#include <gtk/gtkmain.h>

#include "actioneditorw.h"
#include "designerbridgew.h"
#include "formwindoww.h"
#include "objectinspectorw.h"
#include "propertyeditorw.h"
#include "resourceeditorw.h"
#include "signalsloteditorw.h"
#include "widgetboxw.h"

#include "ccfdesigner.h"

static pthread_key_t *envKey = 0;

// 使用uuidgen工具生成ID
CCF_MAIN_BEGIN("ccfdesigner", "ide.ccf.ccdesigner.views.embedded", "{013b0f65-3661-4f17-bacd-1a088d970e29}", "{78e9f085-f7ad-470e-963e-185f36d402ef}")
    CCF_CLASS(DesignerBridgeW, "designerbridgew.h", "designerbridgew.cpp")
    CCF_CLASS(WidgetBoxW, "widgetboxw.h", "widgetboxw.cpp")
    CCF_CLASS(PropertyEditorW, "propertyeditorw.h", "propertyeditorw.cpp")
    CCF_CLASS(ObjectInspectorW, "objectinspectorw.h", "objectinspectorw.cpp")
    CCF_CLASS(FormWindowW, "formwindoww.h", "formwindoww.cpp")
    CCF_CLASS(ActionEditorW, "actioneditorw.h", "actioneditorw.cpp")
    CCF_CLASS(SignalSlotEditorW, "signalsloteditorw.h", "signalsloteditorw.cpp")
    CCF_CLASS(ResourceEditorW, "resourceeditorw.h", "resourceeditorw.cpp")
CCF_MAIN_END()

/**
 * 设计器
 */
JNIEXPORT jlong JNICALL Java_ide_ccf_ccdesigner_views_embedded_DesignerBridgeW_createControl(JNIEnv *env, jclass that, jlong parent, jlong socketWin)
{
    if (!QApplication::instance())
    {
        Display *xdisp = XOpenDisplay(0);
        (void)new QApplication(xdisp);

        #if QT_VERSION >= 0x040400	// Qt版本大于等于4.4
        qApp->setAttribute(Qt::AA_NativeWindows);
        #endif

        qApp->clipboard()->setProperty("useEventLoopWhenWaiting", QVariant(true));

        GtkStyle *style = gtk_widget_get_style((GtkWidget *)parent);
        GdkColor col = style->bg[GTK_STATE_NORMAL];
        QPalette qtpal(QColor(col.red>>8, col.green>>8, col.blue>>8));

        col = style->text[GTK_STATE_SELECTED];
        qtpal.setColor(QPalette::Normal, QPalette::HighlightedText, QColor(col.red>>8, col.green>>8, col.blue>>8));

        col = style->base[GTK_STATE_SELECTED];
        qtpal.setColor(QPalette::Normal, QPalette::Highlight, QColor(col.red>>8, col.green>>8, col.blue>>8));

        QApplication::setPalette(qtpal);
        QFont::insertSubstitution("Sans", "Sans Serif");

        // TODO
        const QString locale =  QLocale::system().name();
        if (!locale.isEmpty())
        {
        	QTranslator translator;
            const QString &designerTrPath = QLatin1String("/home/chengzb/git/IDECCfEclipse/CCFEclipseIntegration/");
            const QString &qtTrPath = QLibraryInfo::location(QLibraryInfo::TranslationsPath);
            const QString &trFile = QLatin1String("designer_") + locale;

            if (translator.load(trFile, qtTrPath) || translator.load(trFile, designerTrPath))
            	qApp->installTranslator(&translator);
        }
    }

    if (!envKey)
    {
        envKey = new pthread_key_t;
        pthread_key_create(envKey, NULL);
    }

    pthread_setspecific(*envKey, env);
    
    DesignerBridgeW *obj = new DesignerBridgeW();
    QX11EmbedWidget *client = new QX11EmbedWidget();
    
    // 第一个客户端必需为其它客户端的父窗口，否则焦点将无效。因为在这个应用程序中，其它客户端无法成为活动窗口。
    obj->setParent(client);
    
    QVBoxLayout *vblayout = new QVBoxLayout(client);
    vblayout->setMargin(0);
    
    Q_UNUSED(that);

    vblayout->addWidget(obj);

    client->embedInto(socketWin);
    client->show();
    return (jlong)obj;
}

JNIEXPORT void JNICALL Java_ide_ccf_ccdesigner_views_embedded_DesignerBridgeW_computeSize(JNIEnv *env, jclass that, jlong handle, jintArray result)
{
    DesignerBridgeW *obj = (DesignerBridgeW*)handle;
    jint *nresult = NULL;
    nresult = env->GetIntArrayElements(result, NULL);
    
    nresult[0] = obj->parentWidget()->sizeHint().width();
    nresult[1] = obj->parentWidget()->sizeHint().height();
    
    env->ReleaseIntArrayElements(result, nresult, 0);
    
    Q_UNUSED(env);
    Q_UNUSED(that);
}

JNIEXPORT void JNICALL Java_ide_ccf_ccdesigner_views_embedded_DesignerBridgeW_resizeControl(JNIEnv *env, jclass that, jlong handle, jint x, jint y, jint width, jint height)
{
    DesignerBridgeW *obj = (DesignerBridgeW*)handle;

    obj->parentWidget()->resize(width, height);
    obj->parentWidget()->move(x, y);
    
    Q_UNUSED(env);
    Q_UNUSED(that);
}

JNIEXPORT void JNICALL Java_ide_ccf_ccdesigner_views_embedded_DesignerBridgeW_disposeControl(JNIEnv *env, jclass that, jlong handle)
{
    DesignerBridgeW *obj = (DesignerBridgeW*)handle;
    QWidget *parentW = obj->topLevelWidget();

    delete parentW;

    Q_UNUSED(env);
    Q_UNUSED(that);
}

JNIEXPORT void JNICALL Java_ide_ccf_ccdesigner_views_embedded_DesignerBridgeW_setFont(JNIEnv *env, jclass that, jlong handle, jstring jni_family, jint size)
{
    DesignerBridgeW *obj = (DesignerBridgeW*)handle;
    const char *utf_family = env->GetStringUTFChars(jni_family, 0);
    QString family = QString::fromUtf8(utf_family);

    env->ReleaseStringUTFChars(jni_family, utf_family);
    
    obj->setFont(QFont(family, size));
    
    Q_UNUSED(that);
}

JNIEXPORT jstring JNICALL Java_ide_ccf_ccdesigner_views_embedded_DesignerBridgeW_pluginFailureString(JNIEnv *env, jclass that, jlong handle)
{
    DesignerBridgeW *obj = (DesignerBridgeW*)handle;

    Q_UNUSED(that);

    QString res = obj->pluginFailureString();

    return env->NewStringUTF(res.toUtf8());
}

JNIEXPORT void JNICALL Java_ide_ccf_ccdesigner_views_embedded_DesignerBridgeW_setPluginPath(JNIEnv *env, jclass that, jlong handle, jstring jni_pluginPath)
{
    DesignerBridgeW *obj = (DesignerBridgeW*)handle;

    Q_UNUSED(that);

    const char *utf_pluginPath = env->GetStringUTFChars(jni_pluginPath, 0);
    QString pluginPath = QString::fromUtf8(utf_pluginPath);

    env->ReleaseStringUTFChars(jni_pluginPath, utf_pluginPath);
    obj->setPluginPath(pluginPath);

    Q_UNUSED(env);
}

JNIEXPORT jboolean JNICALL Java_ide_ccf_ccdesigner_views_embedded_DesignerBridgeW_initializeJambiPlugins(JNIEnv *env, jclass that, jlong handle, jstring jni_jambiBase, jstring jni_jambiPluginPath, jstring jni_customWidgetClassPath, jstring jni_resourcePath, jstring jni_jvm)
{
    DesignerBridgeW *obj = (DesignerBridgeW*)handle;

    Q_UNUSED(that);

    const char *utf_jambiBase = env->GetStringUTFChars(jni_jambiBase, 0);
    QString jambiBase = QString::fromUtf8(utf_jambiBase);
    env->ReleaseStringUTFChars(jni_jambiBase, utf_jambiBase);

    const char *utf_jambiPluginPath = env->GetStringUTFChars(jni_jambiPluginPath, 0);
    QString jambiPluginPath = QString::fromUtf8(utf_jambiPluginPath);
    env->ReleaseStringUTFChars(jni_jambiPluginPath, utf_jambiPluginPath);

    const char *utf_customWidgetClassPath = env->GetStringUTFChars(jni_customWidgetClassPath, 0);
    QString customWidgetClassPath = QString::fromUtf8(utf_customWidgetClassPath);
    env->ReleaseStringUTFChars(jni_customWidgetClassPath, utf_customWidgetClassPath);

    const char *utf_resourcePath = env->GetStringUTFChars(jni_resourcePath, 0);
    QString resourcePath = QString::fromUtf8(utf_resourcePath);
    env->ReleaseStringUTFChars(jni_resourcePath, utf_resourcePath);

    const char *utf_jvm = env->GetStringUTFChars(jni_jvm, 0);
    QString jvm = QString::fromUtf8(utf_jvm);
    env->ReleaseStringUTFChars(jni_jvm, utf_jvm);

    bool res = obj->initializeJambiPlugins(jambiBase, jambiPluginPath, customWidgetClassPath, resourcePath, jvm);

    Q_UNUSED(env);

    return (jboolean)res;
}

JNIEXPORT void JNICALL Java_ide_ccf_ccdesigner_views_embedded_DesignerBridgeW_initialize(JNIEnv *env, jclass that, jlong handle)
{
    DesignerBridgeW *obj = (DesignerBridgeW*)handle;

    Q_UNUSED(that);

    obj->initialize();

    Q_UNUSED(env);
}

JNIEXPORT void JNICALL Java_ide_ccf_ccdesigner_views_embedded_DesignerBridgeW_updateCustomWidgetLocation(JNIEnv *env, jclass that, jlong handle, jstring jni_path)
{
    DesignerBridgeW *obj = (DesignerBridgeW*)handle;

    Q_UNUSED(that);

    const char *utf_path = env->GetStringUTFChars(jni_path, 0);
    QString path = QString::fromUtf8(utf_path);

    env->ReleaseStringUTFChars(jni_path, utf_path);
    obj->updateCustomWidgetLocation(path);

    Q_UNUSED(env);
}

/**
 * 工具箱
 */
JNIEXPORT jlong JNICALL Java_ide_ccf_ccdesigner_views_embedded_WidgetBoxW_createControl(JNIEnv *env, jclass that, jlong parent, jlong socketWin)
{
    if (!QApplication::instance())
    {
        Display *xdisp = XOpenDisplay(0);
        (void)new QApplication(xdisp);

        #if QT_VERSION >= 0x040400
        qApp->setAttribute(Qt::AA_NativeWindows);
        #endif

        qApp->clipboard()->setProperty("useEventLoopWhenWaiting", QVariant(true));
        GtkStyle *style = gtk_widget_get_style((GtkWidget *)parent);
        GdkColor col = style->bg[GTK_STATE_NORMAL];
        QPalette qtpal(QColor(col.red>>8, col.green>>8, col.blue>>8));

        col = style->text[GTK_STATE_SELECTED];
        qtpal.setColor(QPalette::Normal, QPalette::HighlightedText, QColor(col.red>>8, col.green>>8, col.blue>>8));

        col = style->base[GTK_STATE_SELECTED];
        qtpal.setColor(QPalette::Normal, QPalette::Highlight, QColor(col.red>>8, col.green>>8, col.blue>>8));

        QApplication::setPalette(qtpal);
        QFont::insertSubstitution("Sans", "Sans Serif");
    }

    if (!envKey)
    {
        envKey = new pthread_key_t;
        pthread_key_create(envKey, NULL);
    }
    pthread_setspecific(*envKey, env);
    
    WidgetBoxW *obj = new WidgetBoxW();
    QX11EmbedWidget *client = new QX11EmbedWidget();

    obj->setParent(client);
    
    QVBoxLayout *vblayout = new QVBoxLayout(client);
    vblayout->setMargin(0);
    
    Q_UNUSED(that);

    vblayout->addWidget(obj);

    client->embedInto(socketWin);
    client->show();

    return (jlong)obj;
}

JNIEXPORT void JNICALL Java_ide_ccf_ccdesigner_views_embedded_WidgetBoxW_computeSize(JNIEnv *env, jclass that, jlong handle, jintArray result)
{
    WidgetBoxW *obj = (WidgetBoxW*)handle;
    jint *nresult = NULL;
    nresult = env->GetIntArrayElements(result, NULL);
    
    nresult[0] = obj->parentWidget()->sizeHint().width();
    nresult[1] = obj->parentWidget()->sizeHint().height();
    
    env->ReleaseIntArrayElements(result, nresult, 0);
    
    Q_UNUSED(env);
    Q_UNUSED(that);
}

JNIEXPORT void JNICALL Java_ide_ccf_ccdesigner_views_embedded_WidgetBoxW_resizeControl(JNIEnv *env, jclass that, jlong handle, jint x, jint y, jint width, jint height)
{
    WidgetBoxW *obj = (WidgetBoxW*)handle;

    obj->parentWidget()->resize(width, height);
    obj->parentWidget()->move(x, y);
    
    Q_UNUSED(env);
    Q_UNUSED(that);
}

JNIEXPORT void JNICALL Java_ide_ccf_ccdesigner_views_embedded_WidgetBoxW_disposeControl(JNIEnv *env, jclass that, jlong handle)
{
    WidgetBoxW *obj = (WidgetBoxW*)handle;
    QWidget *parentW = obj->topLevelWidget();

    delete parentW;

    Q_UNUSED(env);
    Q_UNUSED(that);
}

JNIEXPORT void JNICALL Java_ide_ccf_ccdesigner_views_embedded_WidgetBoxW_setFont(JNIEnv *env, jclass that, jlong handle, jstring jni_family, jint size)
{
    WidgetBoxW *obj = (WidgetBoxW*)handle;
    const char *utf_family = env->GetStringUTFChars(jni_family, 0);
    QString family = QString::fromUtf8(utf_family);

    env->ReleaseStringUTFChars(jni_family, utf_family);
    
    obj->setFont(QFont(family, size));
    
    Q_UNUSED(that);
}

JNIEXPORT jstring JNICALL Java_ide_ccf_ccdesigner_views_embedded_WidgetBoxW_pluginFailureString(JNIEnv *env, jclass that, jlong handle)
{
    WidgetBoxW *obj = (WidgetBoxW*)handle;

    Q_UNUSED(that);

    QString res = obj->pluginFailureString();

    return env->NewStringUTF(res.toUtf8());
}

JNIEXPORT void JNICALL Java_ide_ccf_ccdesigner_views_embedded_WidgetBoxW_updateCustomWidgetLocation(JNIEnv *env, jclass that, jlong handle, jstring jni_location)
{
    WidgetBoxW *obj = (WidgetBoxW*)handle;

    Q_UNUSED(that);

    const char *utf_location = env->GetStringUTFChars(jni_location, 0);
    QString location = QString::fromUtf8(utf_location);

    env->ReleaseStringUTFChars(jni_location, utf_location);
    obj->updateCustomWidgetLocation(location);

    Q_UNUSED(env);
}

JNIEXPORT void JNICALL Java_ide_ccf_ccdesigner_views_embedded_WidgetBoxW_setBoxEnabled(JNIEnv *env, jclass that, jlong handle, jboolean state)
{
    WidgetBoxW *obj = (WidgetBoxW*)handle;

    Q_UNUSED(that);

    obj->setBoxEnabled(state);

    Q_UNUSED(env);
}

JNIEXPORT void JNICALL Java_ide_ccf_ccdesigner_views_embedded_WidgetBoxW_updateCustomWidgets(JNIEnv *env, jclass that, jlong handle)
{
    WidgetBoxW *obj = (WidgetBoxW*)handle;

    Q_UNUSED(that);

    obj->updateCustomWidgets();

    Q_UNUSED(env);
}

JNIEXPORT jboolean JNICALL Java_ide_ccf_ccdesigner_views_embedded_WidgetBoxW_initializeJambiPlugins(JNIEnv *env, jclass that, jlong handle, jstring jni_jambiBase, jstring jni_jambiPluginPath, jstring jni_customWidgetClassPath, jstring jni_resourcePath, jstring jni_jvm)
{
    WidgetBoxW *obj = (WidgetBoxW*)handle;

    Q_UNUSED(that);

    const char *utf_jambiBase = env->GetStringUTFChars(jni_jambiBase, 0);
    QString jambiBase = QString::fromUtf8(utf_jambiBase);
    env->ReleaseStringUTFChars(jni_jambiBase, utf_jambiBase);

    const char *utf_jambiPluginPath = env->GetStringUTFChars(jni_jambiPluginPath, 0);
    QString jambiPluginPath = QString::fromUtf8(utf_jambiPluginPath);
    env->ReleaseStringUTFChars(jni_jambiPluginPath, utf_jambiPluginPath);

    const char *utf_customWidgetClassPath = env->GetStringUTFChars(jni_customWidgetClassPath, 0);
    QString customWidgetClassPath = QString::fromUtf8(utf_customWidgetClassPath);
    env->ReleaseStringUTFChars(jni_customWidgetClassPath, utf_customWidgetClassPath);

    const char *utf_resourcePath = env->GetStringUTFChars(jni_resourcePath, 0);
    QString resourcePath = QString::fromUtf8(utf_resourcePath);
    env->ReleaseStringUTFChars(jni_resourcePath, utf_resourcePath);

    const char *utf_jvm = env->GetStringUTFChars(jni_jvm, 0);
    QString jvm = QString::fromUtf8(utf_jvm);
    env->ReleaseStringUTFChars(jni_jvm, utf_jvm);

    bool res = obj->initializeJambiPlugins(jambiBase, jambiPluginPath, customWidgetClassPath, resourcePath, jvm);

    Q_UNUSED(env);

    return (jboolean)res;
}

JNIEXPORT void JNICALL Java_ide_ccf_ccdesigner_views_embedded_WidgetBoxW_initialize(JNIEnv *env, jclass that, jlong handle)
{
    WidgetBoxW *obj = (WidgetBoxW*)handle;

    Q_UNUSED(that);

    obj->initialize();

    Q_UNUSED(env);
}

/**
 * 属性编辑器
 */
JNIEXPORT jlong JNICALL Java_ide_ccf_ccdesigner_views_embedded_PropertyEditorW_createControl(JNIEnv *env, jclass that, jlong parent, jlong socketWin)
{
    if (!QApplication::instance())
    {
        Display *xdisp = XOpenDisplay(0);
        (void)new QApplication(xdisp);

        #if QT_VERSION >= 0x040400
        qApp->setAttribute(Qt::AA_NativeWindows);
        #endif

        qApp->clipboard()->setProperty("useEventLoopWhenWaiting", QVariant(true));

        GtkStyle *style = gtk_widget_get_style((GtkWidget *)parent);
        GdkColor col = style->bg[GTK_STATE_NORMAL];
        QPalette qtpal(QColor(col.red>>8, col.green>>8, col.blue>>8));

        col = style->text[GTK_STATE_SELECTED];
        qtpal.setColor(QPalette::Normal, QPalette::HighlightedText, QColor(col.red>>8, col.green>>8, col.blue>>8));

        col = style->base[GTK_STATE_SELECTED];
        qtpal.setColor(QPalette::Normal, QPalette::Highlight, QColor(col.red>>8, col.green>>8, col.blue>>8));

        QApplication::setPalette(qtpal);
        QFont::insertSubstitution("Sans", "Sans Serif");
    }

    if (!envKey)
    {
        envKey = new pthread_key_t;
        pthread_key_create(envKey, NULL);
    }

    pthread_setspecific(*envKey, env);
    
    PropertyEditorW *obj = new PropertyEditorW();
    QX11EmbedWidget *client = new QX11EmbedWidget();
    
    obj->setParent(client);
    
    QVBoxLayout *vblayout = new QVBoxLayout(client);
    vblayout->setMargin(0);
    
    Q_UNUSED(that);

    vblayout->addWidget(obj);

    client->embedInto(socketWin);
    client->show();

    return (jlong)obj;
}

JNIEXPORT void JNICALL Java_ide_ccf_ccdesigner_views_embedded_PropertyEditorW_computeSize(JNIEnv *env, jclass that, jlong handle, jintArray result)
{
    PropertyEditorW *obj = (PropertyEditorW*)handle;
    jint *nresult = NULL;
    nresult = env->GetIntArrayElements(result, NULL);
    
    nresult[0] = obj->parentWidget()->sizeHint().width();
    nresult[1] = obj->parentWidget()->sizeHint().height();
    
    env->ReleaseIntArrayElements(result, nresult, 0);
    
    Q_UNUSED(env);
    Q_UNUSED(that);
}

JNIEXPORT void JNICALL Java_ide_ccf_ccdesigner_views_embedded_PropertyEditorW_resizeControl(JNIEnv *env, jclass that, jlong handle, jint x, jint y, jint width, jint height)
{
    PropertyEditorW *obj = (PropertyEditorW*)handle;

    obj->parentWidget()->resize(width, height);
    obj->parentWidget()->move(x, y);
    
    Q_UNUSED(env);
    Q_UNUSED(that);
}

JNIEXPORT void JNICALL Java_ide_ccf_ccdesigner_views_embedded_PropertyEditorW_disposeControl(JNIEnv *env, jclass that, jlong handle)
{
    PropertyEditorW *obj = (PropertyEditorW*)handle;
    QWidget *parentW = obj->topLevelWidget();

    delete parentW;

    Q_UNUSED(env);
    Q_UNUSED(that);
}

JNIEXPORT void JNICALL Java_ide_ccf_ccdesigner_views_embedded_PropertyEditorW_setFont(JNIEnv *env, jclass that, jlong handle, jstring jni_family, jint size)
{
    PropertyEditorW *obj = (PropertyEditorW*)handle;
    const char *utf_family = env->GetStringUTFChars(jni_family, 0);
    QString family = QString::fromUtf8(utf_family);

    env->ReleaseStringUTFChars(jni_family, utf_family);
    
    obj->setFont(QFont(family, size));
    
    Q_UNUSED(that);
}

JNIEXPORT jstring JNICALL Java_ide_ccf_ccdesigner_views_embedded_PropertyEditorW_pluginFailureString(JNIEnv *env, jclass that, jlong handle)
{
    PropertyEditorW *obj = (PropertyEditorW*)handle;

    Q_UNUSED(that);

    QString res = obj->pluginFailureString();

    return env->NewStringUTF(res.toUtf8());
}

JNIEXPORT void JNICALL Java_ide_ccf_ccdesigner_views_embedded_PropertyEditorW_clearSheet(JNIEnv *env, jclass that, jlong handle)
{
    PropertyEditorW *obj = (PropertyEditorW*)handle;

    Q_UNUSED(that);

    obj->clearSheet();

    Q_UNUSED(env);
}

JNIEXPORT jboolean JNICALL Java_ide_ccf_ccdesigner_views_embedded_PropertyEditorW_initializeJambiPlugins(JNIEnv *env, jclass that, jlong handle, jstring jni_jambiBase, jstring jni_jambiPluginPath, jstring jni_customWidgetClassPath, jstring jni_resourcePath, jstring jni_jvm)
{
    PropertyEditorW *obj = (PropertyEditorW*)handle;

    Q_UNUSED(that);

    const char *utf_jambiBase = env->GetStringUTFChars(jni_jambiBase, 0);
    QString jambiBase = QString::fromUtf8(utf_jambiBase);
    env->ReleaseStringUTFChars(jni_jambiBase, utf_jambiBase);

    const char *utf_jambiPluginPath = env->GetStringUTFChars(jni_jambiPluginPath, 0);
    QString jambiPluginPath = QString::fromUtf8(utf_jambiPluginPath);
    env->ReleaseStringUTFChars(jni_jambiPluginPath, utf_jambiPluginPath);

    const char *utf_customWidgetClassPath = env->GetStringUTFChars(jni_customWidgetClassPath, 0);
    QString customWidgetClassPath = QString::fromUtf8(utf_customWidgetClassPath);
    env->ReleaseStringUTFChars(jni_customWidgetClassPath, utf_customWidgetClassPath);

    const char *utf_resourcePath = env->GetStringUTFChars(jni_resourcePath, 0);
    QString resourcePath = QString::fromUtf8(utf_resourcePath);
    env->ReleaseStringUTFChars(jni_resourcePath, utf_resourcePath);

    const char *utf_jvm = env->GetStringUTFChars(jni_jvm, 0);
    QString jvm = QString::fromUtf8(utf_jvm);
    env->ReleaseStringUTFChars(jni_jvm, utf_jvm);

    bool res = obj->initializeJambiPlugins(jambiBase, jambiPluginPath, customWidgetClassPath, resourcePath, jvm);

    Q_UNUSED(env);

    return (jboolean)res;
}

JNIEXPORT void JNICALL Java_ide_ccf_ccdesigner_views_embedded_PropertyEditorW_initialize(JNIEnv *env, jclass that, jlong handle)
{
    PropertyEditorW *obj = (PropertyEditorW*)handle;

    Q_UNUSED(that);

    obj->initialize();

    Q_UNUSED(env);
}

JNIEXPORT void JNICALL Java_ide_ccf_ccdesigner_views_embedded_PropertyEditorW_updateCustomWidgetLocation(JNIEnv *env, jclass that, jlong handle, jstring jni_path)
{
    PropertyEditorW *obj = (PropertyEditorW*)handle;

    Q_UNUSED(that);

    const char *utf_path = env->GetStringUTFChars(jni_path, 0);
    QString path = QString::fromUtf8(utf_path);

    env->ReleaseStringUTFChars(jni_path, utf_path);
    obj->updateCustomWidgetLocation(path);

    Q_UNUSED(env);
}

/**
 * 对象浏览器
 */
JNIEXPORT jlong JNICALL Java_ide_ccf_ccdesigner_views_embedded_ObjectInspectorW_createControl(JNIEnv *env, jclass that, jlong parent, jlong socketWin)
{
    if (!QApplication::instance())
    {
        Display *xdisp = XOpenDisplay(0);
        (void)new QApplication(xdisp);

        #if QT_VERSION >= 0x040400
        qApp->setAttribute(Qt::AA_NativeWindows);
        #endif

        qApp->clipboard()->setProperty("useEventLoopWhenWaiting", QVariant(true));

        GtkStyle *style = gtk_widget_get_style((GtkWidget *)parent);
        GdkColor col = style->bg[GTK_STATE_NORMAL];
        QPalette qtpal(QColor(col.red>>8, col.green>>8, col.blue>>8));

        col = style->text[GTK_STATE_SELECTED];
        qtpal.setColor(QPalette::Normal, QPalette::HighlightedText, QColor(col.red>>8, col.green>>8, col.blue>>8));

        col = style->base[GTK_STATE_SELECTED];
        qtpal.setColor(QPalette::Normal, QPalette::Highlight, QColor(col.red>>8, col.green>>8, col.blue>>8));

        QApplication::setPalette(qtpal);
        QFont::insertSubstitution("Sans", "Sans Serif");
    }

    if (!envKey)
    {
        envKey = new pthread_key_t;
        pthread_key_create(envKey, NULL);
    }

    pthread_setspecific(*envKey, env);
    
    ObjectInspectorW *obj = new ObjectInspectorW();
    QX11EmbedWidget *client = new QX11EmbedWidget();

    obj->setParent(client);
    
    QVBoxLayout *vblayout = new QVBoxLayout(client);
    vblayout->setMargin(0);
    
    Q_UNUSED(that);

    vblayout->addWidget(obj);

    client->embedInto(socketWin);
    client->show();

    return (jlong)obj;
}

JNIEXPORT void JNICALL Java_ide_ccf_ccdesigner_views_embedded_ObjectInspectorW_computeSize(JNIEnv *env, jclass that, jlong handle, jintArray result)
{
    ObjectInspectorW *obj = (ObjectInspectorW*)handle;
    jint *nresult = NULL;
    nresult = env->GetIntArrayElements(result, NULL);
    
    nresult[0] = obj->parentWidget()->sizeHint().width();
    nresult[1] = obj->parentWidget()->sizeHint().height();
    
    env->ReleaseIntArrayElements(result, nresult, 0);
    
    Q_UNUSED(env);
    Q_UNUSED(that);
}

JNIEXPORT void JNICALL Java_ide_ccf_ccdesigner_views_embedded_ObjectInspectorW_resizeControl(JNIEnv *env, jclass that, jlong handle, jint x, jint y, jint width, jint height)
{
    ObjectInspectorW *obj = (ObjectInspectorW*)handle;

    obj->parentWidget()->resize(width, height);
    obj->parentWidget()->move(x, y);
    
    Q_UNUSED(env);
    Q_UNUSED(that);
}

JNIEXPORT void JNICALL Java_ide_ccf_ccdesigner_views_embedded_ObjectInspectorW_disposeControl(JNIEnv *env, jclass that, jlong handle)
{
    ObjectInspectorW *obj = (ObjectInspectorW*)handle;
    QWidget *parentW = obj->topLevelWidget();

    delete parentW;

    Q_UNUSED(env);
    Q_UNUSED(that);
}

JNIEXPORT void JNICALL Java_ide_ccf_ccdesigner_views_embedded_ObjectInspectorW_setFont(JNIEnv *env, jclass that, jlong handle, jstring jni_family, jint size)
{
    ObjectInspectorW *obj = (ObjectInspectorW*)handle;
    const char *utf_family = env->GetStringUTFChars(jni_family, 0);
    QString family = QString::fromUtf8(utf_family);

    env->ReleaseStringUTFChars(jni_family, utf_family);
    
    obj->setFont(QFont(family, size));
    
    Q_UNUSED(that);
}

JNIEXPORT jstring JNICALL Java_ide_ccf_ccdesigner_views_embedded_ObjectInspectorW_pluginFailureString(JNIEnv *env, jclass that, jlong handle)
{
    ObjectInspectorW *obj = (ObjectInspectorW*)handle;

    Q_UNUSED(that);

    QString res = obj->pluginFailureString();

    return env->NewStringUTF(res.toUtf8());
}

JNIEXPORT jboolean JNICALL Java_ide_ccf_ccdesigner_views_embedded_ObjectInspectorW_initializeJambiPlugins(JNIEnv *env, jclass that, jlong handle, jstring jni_jambiBase, jstring jni_jambiPluginPath, jstring jni_customWidgetClassPath, jstring jni_resourcePath, jstring jni_jvm)
{
    ObjectInspectorW *obj = (ObjectInspectorW*)handle;

    Q_UNUSED(that);

    const char *utf_jambiBase = env->GetStringUTFChars(jni_jambiBase, 0);
    QString jambiBase = QString::fromUtf8(utf_jambiBase);
    env->ReleaseStringUTFChars(jni_jambiBase, utf_jambiBase);

    const char *utf_jambiPluginPath = env->GetStringUTFChars(jni_jambiPluginPath, 0);
    QString jambiPluginPath = QString::fromUtf8(utf_jambiPluginPath);
    env->ReleaseStringUTFChars(jni_jambiPluginPath, utf_jambiPluginPath);

    const char *utf_customWidgetClassPath = env->GetStringUTFChars(jni_customWidgetClassPath, 0);
    QString customWidgetClassPath = QString::fromUtf8(utf_customWidgetClassPath);
    env->ReleaseStringUTFChars(jni_customWidgetClassPath, utf_customWidgetClassPath);

    const char *utf_resourcePath = env->GetStringUTFChars(jni_resourcePath, 0);
    QString resourcePath = QString::fromUtf8(utf_resourcePath);
    env->ReleaseStringUTFChars(jni_resourcePath, utf_resourcePath);

    const char *utf_jvm = env->GetStringUTFChars(jni_jvm, 0);
    QString jvm = QString::fromUtf8(utf_jvm);
    env->ReleaseStringUTFChars(jni_jvm, utf_jvm);

    bool res = obj->initializeJambiPlugins(jambiBase, jambiPluginPath, customWidgetClassPath, resourcePath, jvm);

    Q_UNUSED(env);

    return (jboolean)res;
}

JNIEXPORT void JNICALL Java_ide_ccf_ccdesigner_views_embedded_ObjectInspectorW_initialize(JNIEnv *env, jclass that, jlong handle)
{
    ObjectInspectorW *obj = (ObjectInspectorW*)handle;

    Q_UNUSED(that);

    obj->initialize();

    Q_UNUSED(env);
}

JNIEXPORT void JNICALL Java_ide_ccf_ccdesigner_views_embedded_ObjectInspectorW_updateCustomWidgetLocation(JNIEnv *env, jclass that, jlong handle, jstring jni_path)
{
    ObjectInspectorW *obj = (ObjectInspectorW*)handle;

    Q_UNUSED(that);

    const char *utf_path = env->GetStringUTFChars(jni_path, 0);
    QString path = QString::fromUtf8(utf_path);

    env->ReleaseStringUTFChars(jni_path, utf_path);
    obj->updateCustomWidgetLocation(path);

    Q_UNUSED(env);
}

/**
 * 窗体设计窗口
 */
JNIEXPORT jlong JNICALL Java_ide_ccf_ccdesigner_views_embedded_FormWindowW_createControl(JNIEnv *env, jclass that, jlong parent, jlong socketWin)
{
    if (!QApplication::instance())
    {
        Display *xdisp = XOpenDisplay(0);
        (void)new QApplication(xdisp);

        #if QT_VERSION >= 0x040400
        qApp->setAttribute(Qt::AA_NativeWindows);
        #endif

        qApp->clipboard()->setProperty("useEventLoopWhenWaiting", QVariant(true));

        GtkStyle *style = gtk_widget_get_style((GtkWidget *)parent);
        GdkColor col = style->bg[GTK_STATE_NORMAL];
        QPalette qtpal(QColor(col.red>>8, col.green>>8, col.blue>>8));

        col = style->text[GTK_STATE_SELECTED];
        qtpal.setColor(QPalette::Normal, QPalette::HighlightedText, QColor(col.red>>8, col.green>>8, col.blue>>8));

        col = style->base[GTK_STATE_SELECTED];
        qtpal.setColor(QPalette::Normal, QPalette::Highlight, QColor(col.red>>8, col.green>>8, col.blue>>8));

        QApplication::setPalette(qtpal);
        QFont::insertSubstitution("Sans", "Sans Serif");
    }

    if (!envKey)
    {
        envKey = new pthread_key_t;
        pthread_key_create(envKey, NULL);
    }
    pthread_setspecific(*envKey, env);
    
    FormWindowW *obj = new FormWindowW();
    QX11EmbedWidget *client = new QX11EmbedWidget();

    obj->setParent(client);
    
    QVBoxLayout *vblayout = new QVBoxLayout(client);
    vblayout->setMargin(0);
    
    FormWindowWListener *lstnr = new FormWindowWListener(obj, envKey, that);
    QObject::connect(obj, SIGNAL(actionChanged(int)), lstnr, SLOT(slot_actionChanged(int)));
    QObject::connect(obj, SIGNAL(checkActiveWindow()), lstnr, SLOT(slot_checkActiveWindow()));
    QObject::connect(obj, SIGNAL(resourceFilesChanged()), lstnr, SLOT(slot_resourceFilesChanged()));
    QObject::connect(obj, SIGNAL(updateDirtyFlag()), lstnr, SLOT(slot_updateDirtyFlag()));
    vblayout->addWidget(obj);

    client->embedInto(socketWin);
    client->show();

    return (jlong)obj;
}

JNIEXPORT void JNICALL Java_ide_ccf_ccdesigner_views_embedded_FormWindowW_computeSize(JNIEnv *env, jclass that, jlong handle, jintArray result)
{
    FormWindowW *obj = (FormWindowW*)handle;
    jint *nresult = NULL;
    nresult = env->GetIntArrayElements(result, NULL);
    
    nresult[0] = obj->parentWidget()->sizeHint().width();
    nresult[1] = obj->parentWidget()->sizeHint().height();
    
    env->ReleaseIntArrayElements(result, nresult, 0);
    
    Q_UNUSED(env);
    Q_UNUSED(that);
}

JNIEXPORT void JNICALL Java_ide_ccf_ccdesigner_views_embedded_FormWindowW_resizeControl(JNIEnv *env, jclass that, jlong handle, jint x, jint y, jint width, jint height)
{
    FormWindowW *obj = (FormWindowW*)handle;

    obj->parentWidget()->resize(width, height);
    obj->parentWidget()->move(x, y);
    
    Q_UNUSED(env);
    Q_UNUSED(that);
}

JNIEXPORT void JNICALL Java_ide_ccf_ccdesigner_views_embedded_FormWindowW_disposeControl(JNIEnv *env, jclass that, jlong handle)
{
    FormWindowW *obj = (FormWindowW*)handle;
    QWidget *parentW = obj->topLevelWidget();

    delete parentW;

    Q_UNUSED(env);
    Q_UNUSED(that);
}

JNIEXPORT void JNICALL Java_ide_ccf_ccdesigner_views_embedded_FormWindowW_setFont(JNIEnv *env, jclass that, jlong handle, jstring jni_family, jint size)
{
    FormWindowW *obj = (FormWindowW*)handle;
    const char *utf_family = env->GetStringUTFChars(jni_family, 0);
    QString family = QString::fromUtf8(utf_family);

    env->ReleaseStringUTFChars(jni_family, utf_family);
    
    obj->setFont(QFont(family, size));
    
    Q_UNUSED(that);
}

JNIEXPORT jstring JNICALL Java_ide_ccf_ccdesigner_views_embedded_FormWindowW_pluginFailureString(JNIEnv *env, jclass that, jlong handle)
{
    FormWindowW *obj = (FormWindowW*)handle;

    Q_UNUSED(that);

    QString res = obj->pluginFailureString();

    return env->NewStringUTF(res.toUtf8());
}

JNIEXPORT void JNICALL Java_ide_ccf_ccdesigner_views_embedded_FormWindowW_open(JNIEnv *env, jclass that, jlong handle, jstring jni_fileName)
{
    FormWindowW *obj = (FormWindowW*)handle;

    Q_UNUSED(that);

    const char *utf_fileName = env->GetStringUTFChars(jni_fileName, 0);
    QString fileName = QString::fromUtf8(utf_fileName);

    env->ReleaseStringUTFChars(jni_fileName, utf_fileName);
    obj->open(fileName);

    Q_UNUSED(env);
}

JNIEXPORT jboolean JNICALL Java_ide_ccf_ccdesigner_views_embedded_FormWindowW_save(JNIEnv *env, jclass that, jlong handle)
{
    FormWindowW *obj = (FormWindowW*)handle;

    Q_UNUSED(that);

    bool res = obj->save();

    Q_UNUSED(env);

    return (jboolean)res;
}

JNIEXPORT jboolean JNICALL Java_ide_ccf_ccdesigner_views_embedded_FormWindowW_saveAs(JNIEnv *env, jclass that, jlong handle, jstring jni_fileName)
{
    FormWindowW *obj = (FormWindowW*)handle;

    Q_UNUSED(that);

    const char *utf_fileName = env->GetStringUTFChars(jni_fileName, 0);
    QString fileName = QString::fromUtf8(utf_fileName);

    env->ReleaseStringUTFChars(jni_fileName, utf_fileName);

    bool res = obj->saveAs(fileName);

    Q_UNUSED(env);

    return (jboolean)res;
}

JNIEXPORT jboolean JNICALL Java_ide_ccf_ccdesigner_views_embedded_FormWindowW_isDirty(JNIEnv *env, jclass that, jlong handle)
{
    FormWindowW *obj = (FormWindowW*)handle;

    Q_UNUSED(that);

    bool res = obj->isDirty();

    Q_UNUSED(env);

    return (jboolean)res;
}

JNIEXPORT void JNICALL Java_ide_ccf_ccdesigner_views_embedded_FormWindowW_close(JNIEnv *env, jclass that, jlong handle)
{
    FormWindowW *obj = (FormWindowW*)handle;

    Q_UNUSED(that);

    obj->close();

    Q_UNUSED(env);
}

JNIEXPORT void JNICALL Java_ide_ccf_ccdesigner_views_embedded_FormWindowW_initialize(JNIEnv *env, jclass that, jlong handle)
{
    FormWindowW *obj = (FormWindowW*)handle;

    Q_UNUSED(that);

    obj->initialize();

    Q_UNUSED(env);
}

JNIEXPORT void JNICALL Java_ide_ccf_ccdesigner_views_embedded_FormWindowW_setActiveFormWindow(JNIEnv *env, jclass that, jlong handle)
{
    FormWindowW *obj = (FormWindowW*)handle;

    Q_UNUSED(that);

    obj->setActiveFormWindow();

    Q_UNUSED(env);
}

JNIEXPORT void JNICALL Java_ide_ccf_ccdesigner_views_embedded_FormWindowW_setObjectName(JNIEnv *env, jclass that, jlong handle, jstring jni_objectName)
{
    FormWindowW *obj = (FormWindowW*)handle;

    Q_UNUSED(that);

    const char *utf_objectName = env->GetStringUTFChars(jni_objectName, 0);
    QString objectName = QString::fromUtf8(utf_objectName);

    env->ReleaseStringUTFChars(jni_objectName, utf_objectName);
    obj->setObjectName(objectName);

    Q_UNUSED(env);
}

JNIEXPORT jboolean JNICALL Java_ide_ccf_ccdesigner_views_embedded_FormWindowW_initializeJambiPlugins(JNIEnv *env, jclass that, jlong handle, jstring jni_jambiBase, jstring jni_jambiPluginPath, jstring jni_customWidgetClassPath, jstring jni_resourcePath, jstring jni_jvm)
{
    FormWindowW *obj = (FormWindowW*)handle;

    Q_UNUSED(that);

    const char *utf_jambiBase = env->GetStringUTFChars(jni_jambiBase, 0);
    QString jambiBase = QString::fromUtf8(utf_jambiBase);
    env->ReleaseStringUTFChars(jni_jambiBase, utf_jambiBase);

    const char *utf_jambiPluginPath = env->GetStringUTFChars(jni_jambiPluginPath, 0);
    QString jambiPluginPath = QString::fromUtf8(utf_jambiPluginPath);
    env->ReleaseStringUTFChars(jni_jambiPluginPath, utf_jambiPluginPath);

    const char *utf_customWidgetClassPath = env->GetStringUTFChars(jni_customWidgetClassPath, 0);
    QString customWidgetClassPath = QString::fromUtf8(utf_customWidgetClassPath);
    env->ReleaseStringUTFChars(jni_customWidgetClassPath, utf_customWidgetClassPath);

    const char *utf_resourcePath = env->GetStringUTFChars(jni_resourcePath, 0);
    QString resourcePath = QString::fromUtf8(utf_resourcePath);
    env->ReleaseStringUTFChars(jni_resourcePath, utf_resourcePath);

    const char *utf_jvm = env->GetStringUTFChars(jni_jvm, 0);
    QString jvm = QString::fromUtf8(utf_jvm);
    env->ReleaseStringUTFChars(jni_jvm, utf_jvm);

    bool res = obj->initializeJambiPlugins(jambiBase, jambiPluginPath, customWidgetClassPath, resourcePath, jvm);

    Q_UNUSED(env);

    return (jboolean)res;
}

JNIEXPORT void JNICALL Java_ide_ccf_ccdesigner_views_embedded_FormWindowW_updateJambiResourcePath(JNIEnv *env, jclass that, jlong handle, jstring jni_resourcePath)
{
    FormWindowW *obj = (FormWindowW*)handle;

    Q_UNUSED(that);

    const char *utf_resourcePath = env->GetStringUTFChars(jni_resourcePath, 0);
    QString resourcePath = QString::fromUtf8(utf_resourcePath);

    env->ReleaseStringUTFChars(jni_resourcePath, utf_resourcePath);
    obj->updateJambiResourcePath(resourcePath);

    Q_UNUSED(env);
}

JNIEXPORT void JNICALL Java_ide_ccf_ccdesigner_views_embedded_FormWindowW_updateCustomWidgetLocation(JNIEnv *env, jclass that, jlong handle, jstring jni_path)
{
    FormWindowW *obj = (FormWindowW*)handle;

    Q_UNUSED(that);

    const char *utf_path = env->GetStringUTFChars(jni_path, 0);
    QString path = QString::fromUtf8(utf_path);

    env->ReleaseStringUTFChars(jni_path, utf_path);
    obj->updateCustomWidgetLocation(path);

    Q_UNUSED(env);
}

JNIEXPORT jint JNICALL Java_ide_ccf_ccdesigner_views_embedded_FormWindowW_actionCount(JNIEnv *env, jclass that, jlong handle)
{
    FormWindowW *obj = (FormWindowW*)handle;

    Q_UNUSED(that);

    int res = obj->actionCount();

    Q_UNUSED(env);

    return (jint)res;
}

JNIEXPORT jint JNICALL Java_ide_ccf_ccdesigner_views_embedded_FormWindowW_staticActionCount(JNIEnv *env, jclass that, jlong handle)
{
    FormWindowW *obj = (FormWindowW*)handle;

    Q_UNUSED(that);

    int res = obj->staticActionCount();

    Q_UNUSED(env);

    return (jint)res;
}

JNIEXPORT jstring JNICALL Java_ide_ccf_ccdesigner_views_embedded_FormWindowW_actionName(JNIEnv *env, jclass that, jlong handle, jint id)
{
    FormWindowW *obj = (FormWindowW*)handle;

    Q_UNUSED(that);

    QString res = obj->actionName(id);

    return env->NewStringUTF(res.toUtf8());
}

JNIEXPORT jstring JNICALL Java_ide_ccf_ccdesigner_views_embedded_FormWindowW_actionToolTip(JNIEnv *env, jclass that, jlong handle, jint id)
{
    FormWindowW *obj = (FormWindowW*)handle;

    Q_UNUSED(that);

    QString res = obj->actionToolTip(id);

    return env->NewStringUTF(res.toUtf8());
}

JNIEXPORT void JNICALL Java_ide_ccf_ccdesigner_views_embedded_FormWindowW_actionTrigger(JNIEnv *env, jclass that, jlong handle, jint id)
{
    FormWindowW *obj = (FormWindowW*)handle;

    Q_UNUSED(that);

    obj->actionTrigger(id);

    Q_UNUSED(env);
}

JNIEXPORT jboolean JNICALL Java_ide_ccf_ccdesigner_views_embedded_FormWindowW_isEnabled(JNIEnv *env, jclass that, jlong handle, jint id)
{
    FormWindowW *obj = (FormWindowW*)handle;

    Q_UNUSED(that);

    bool res = obj->isEnabled(id);

    Q_UNUSED(env);

    return (jboolean)res;
}

JNIEXPORT jint JNICALL Java_ide_ccf_ccdesigner_views_embedded_FormWindowW_toolCount(JNIEnv *env, jclass that, jlong handle)
{
    FormWindowW *obj = (FormWindowW*)handle;

    Q_UNUSED(that);

    int res = obj->toolCount();

    Q_UNUSED(env);

    return (jint)res;
}

JNIEXPORT jstring JNICALL Java_ide_ccf_ccdesigner_views_embedded_FormWindowW_toolName(JNIEnv *env, jclass that, jlong handle, jint index)
{
    FormWindowW *obj = (FormWindowW*)handle;

    Q_UNUSED(that);

    QString res = obj->toolName(index);

    return env->NewStringUTF(res.toUtf8());
}

JNIEXPORT jstring JNICALL Java_ide_ccf_ccdesigner_views_embedded_FormWindowW_toolToolTip(JNIEnv *env, jclass that, jlong handle, jint index)
{
    FormWindowW *obj = (FormWindowW*)handle;

    Q_UNUSED(that);

    QString res = obj->toolToolTip(index);

    return env->NewStringUTF(res.toUtf8());
}

JNIEXPORT jint JNICALL Java_ide_ccf_ccdesigner_views_embedded_FormWindowW_currentTool(JNIEnv *env, jclass that, jlong handle)
{
    FormWindowW *obj = (FormWindowW*)handle;

    Q_UNUSED(that);

    int res = obj->currentTool();

    Q_UNUSED(env);

    return (jint)res;
}

JNIEXPORT void JNICALL Java_ide_ccf_ccdesigner_views_embedded_FormWindowW_setCurrentTool(JNIEnv *env, jclass that, jlong handle, jint index)
{
    FormWindowW *obj = (FormWindowW*)handle;

    Q_UNUSED(that);

    obj->setCurrentTool(index);

    Q_UNUSED(env);
}

/**
 * 动作编辑器
 */
JNIEXPORT jlong JNICALL Java_ide_ccf_ccdesigner_views_embedded_ActionEditorW_createControl(JNIEnv *env, jclass that, jlong parent, jlong socketWin)
{
    if (!QApplication::instance())
    {
        Display *xdisp = XOpenDisplay(0);
        (void)new QApplication(xdisp);

        #if QT_VERSION >= 0x040400
        qApp->setAttribute(Qt::AA_NativeWindows);
        #endif

        qApp->clipboard()->setProperty("useEventLoopWhenWaiting", QVariant(true));

        GtkStyle *style = gtk_widget_get_style((GtkWidget *)parent);
        GdkColor col = style->bg[GTK_STATE_NORMAL];
        QPalette qtpal(QColor(col.red>>8, col.green>>8, col.blue>>8));

        col = style->text[GTK_STATE_SELECTED];
        qtpal.setColor(QPalette::Normal, QPalette::HighlightedText, QColor(col.red>>8, col.green>>8, col.blue>>8));

        col = style->base[GTK_STATE_SELECTED];
        qtpal.setColor(QPalette::Normal, QPalette::Highlight, QColor(col.red>>8, col.green>>8, col.blue>>8));

        QApplication::setPalette(qtpal);
        QFont::insertSubstitution("Sans", "Sans Serif");
    }

    if (!envKey)
    {
        envKey = new pthread_key_t;
        pthread_key_create(envKey, NULL);
    }

    pthread_setspecific(*envKey, env);
    
    ActionEditorW *obj = new ActionEditorW();
    QX11EmbedWidget *client = new QX11EmbedWidget();

    obj->setParent(client);
    
    QVBoxLayout *vblayout = new QVBoxLayout(client);
    vblayout->setMargin(0);
    
    Q_UNUSED(that);

    vblayout->addWidget(obj);

    client->embedInto(socketWin);
    client->show();

    return (jlong)obj;
}

JNIEXPORT void JNICALL Java_ide_ccf_ccdesigner_views_embedded_ActionEditorW_computeSize(JNIEnv *env, jclass that, jlong handle, jintArray result)
{
    ActionEditorW *obj = (ActionEditorW*)handle;
    jint *nresult = NULL;
    nresult = env->GetIntArrayElements(result, NULL);
    
    nresult[0] = obj->parentWidget()->sizeHint().width();
    nresult[1] = obj->parentWidget()->sizeHint().height();
    
    env->ReleaseIntArrayElements(result, nresult, 0);
    
    Q_UNUSED(env);
    Q_UNUSED(that);
}

JNIEXPORT void JNICALL Java_ide_ccf_ccdesigner_views_embedded_ActionEditorW_resizeControl(JNIEnv *env, jclass that, jlong handle, jint x, jint y, jint width, jint height)
{
    ActionEditorW *obj = (ActionEditorW*)handle;

    obj->parentWidget()->resize(width, height);
    obj->parentWidget()->move(x, y);
    
    Q_UNUSED(env);
    Q_UNUSED(that);
}

JNIEXPORT void JNICALL Java_ide_ccf_ccdesigner_views_embedded_ActionEditorW_disposeControl(JNIEnv *env, jclass that, jlong handle)
{
    ActionEditorW *obj = (ActionEditorW*)handle;
    QWidget *parentW = obj->topLevelWidget();

    delete parentW;

    Q_UNUSED(env);
    Q_UNUSED(that);
}

JNIEXPORT void JNICALL Java_ide_ccf_ccdesigner_views_embedded_ActionEditorW_setFont(JNIEnv *env, jclass that, jlong handle, jstring jni_family, jint size)
{
    ActionEditorW *obj = (ActionEditorW*)handle;
    const char *utf_family = env->GetStringUTFChars(jni_family, 0);
    QString family = QString::fromUtf8(utf_family);

    env->ReleaseStringUTFChars(jni_family, utf_family);
    
    obj->setFont(QFont(family, size));
    
    Q_UNUSED(that);
}

JNIEXPORT jstring JNICALL Java_ide_ccf_ccdesigner_views_embedded_ActionEditorW_pluginFailureString(JNIEnv *env, jclass that, jlong handle)
{
    ActionEditorW *obj = (ActionEditorW*)handle;

    Q_UNUSED(that);

    QString res = obj->pluginFailureString();

    return env->NewStringUTF(res.toUtf8());
}

JNIEXPORT jboolean JNICALL Java_ide_ccf_ccdesigner_views_embedded_ActionEditorW_initializeJambiPlugins(JNIEnv *env, jclass that, jlong handle, jstring jni_jambiBase, jstring jni_jambiPluginPath, jstring jni_customWidgetClassPath, jstring jni_resourcePath, jstring jni_jvm)
{
    ActionEditorW *obj = (ActionEditorW*)handle;

    Q_UNUSED(that);

    const char *utf_jambiBase = env->GetStringUTFChars(jni_jambiBase, 0);
    QString jambiBase = QString::fromUtf8(utf_jambiBase);
    env->ReleaseStringUTFChars(jni_jambiBase, utf_jambiBase);

    const char *utf_jambiPluginPath = env->GetStringUTFChars(jni_jambiPluginPath, 0);
    QString jambiPluginPath = QString::fromUtf8(utf_jambiPluginPath);
    env->ReleaseStringUTFChars(jni_jambiPluginPath, utf_jambiPluginPath);

    const char *utf_customWidgetClassPath = env->GetStringUTFChars(jni_customWidgetClassPath, 0);
    QString customWidgetClassPath = QString::fromUtf8(utf_customWidgetClassPath);
    env->ReleaseStringUTFChars(jni_customWidgetClassPath, utf_customWidgetClassPath);

    const char *utf_resourcePath = env->GetStringUTFChars(jni_resourcePath, 0);
    QString resourcePath = QString::fromUtf8(utf_resourcePath);
    env->ReleaseStringUTFChars(jni_resourcePath, utf_resourcePath);

    const char *utf_jvm = env->GetStringUTFChars(jni_jvm, 0);
    QString jvm = QString::fromUtf8(utf_jvm);
    env->ReleaseStringUTFChars(jni_jvm, utf_jvm);

    bool res = obj->initializeJambiPlugins(jambiBase, jambiPluginPath, customWidgetClassPath, resourcePath, jvm);

    Q_UNUSED(env);

    return (jboolean)res;
}

JNIEXPORT void JNICALL Java_ide_ccf_ccdesigner_views_embedded_ActionEditorW_initialize(JNIEnv *env, jclass that, jlong handle)
{
    ActionEditorW *obj = (ActionEditorW*)handle;

    Q_UNUSED(that);

    obj->initialize();

    Q_UNUSED(env);
}

JNIEXPORT void JNICALL Java_ide_ccf_ccdesigner_views_embedded_ActionEditorW_updateCustomWidgetLocation(JNIEnv *env, jclass that, jlong handle, jstring jni_path)
{
    ActionEditorW *obj = (ActionEditorW*)handle;

    Q_UNUSED(that);

    const char *utf_path = env->GetStringUTFChars(jni_path, 0);
    QString path = QString::fromUtf8(utf_path);

    env->ReleaseStringUTFChars(jni_path, utf_path);
    obj->updateCustomWidgetLocation(path);

    Q_UNUSED(env);
}

/**
 * 信号/槽编辑器
 */
JNIEXPORT jlong JNICALL Java_ide_ccf_ccdesigner_views_embedded_SignalSlotEditorW_createControl(JNIEnv *env, jclass that, jlong parent, jlong socketWin)
{
    if (!QApplication::instance())
    {
        Display *xdisp = XOpenDisplay(0);
        (void)new QApplication(xdisp);

        #if QT_VERSION >= 0x040400
        qApp->setAttribute(Qt::AA_NativeWindows);
        #endif

        qApp->clipboard()->setProperty("useEventLoopWhenWaiting", QVariant(true));

        GtkStyle *style = gtk_widget_get_style((GtkWidget *)parent);
        GdkColor col = style->bg[GTK_STATE_NORMAL];
        QPalette qtpal(QColor(col.red>>8, col.green>>8, col.blue>>8));

        col = style->text[GTK_STATE_SELECTED];
        qtpal.setColor(QPalette::Normal, QPalette::HighlightedText, QColor(col.red>>8, col.green>>8, col.blue>>8));

        col = style->base[GTK_STATE_SELECTED];
        qtpal.setColor(QPalette::Normal, QPalette::Highlight, QColor(col.red>>8, col.green>>8, col.blue>>8));

        QApplication::setPalette(qtpal);
        QFont::insertSubstitution("Sans", "Sans Serif");
    }

    if (!envKey)
    {
        envKey = new pthread_key_t;
        pthread_key_create(envKey, NULL);
    }

    pthread_setspecific(*envKey, env);
    
    SignalSlotEditorW *obj = new SignalSlotEditorW();
    QX11EmbedWidget *client = new QX11EmbedWidget();
    
    obj->setParent(client);
    
    QVBoxLayout *vblayout = new QVBoxLayout(client);
    vblayout->setMargin(0);
    
    Q_UNUSED(that);

    vblayout->addWidget(obj);

    client->embedInto(socketWin);
    client->show();

    return (jlong)obj;
}

JNIEXPORT void JNICALL Java_ide_ccf_ccdesigner_views_embedded_SignalSlotEditorW_computeSize(JNIEnv *env, jclass that, jlong handle, jintArray result)
{
    SignalSlotEditorW *obj = (SignalSlotEditorW*)handle;
    jint *nresult = NULL;
    nresult = env->GetIntArrayElements(result, NULL);
    
    nresult[0] = obj->parentWidget()->sizeHint().width();
    nresult[1] = obj->parentWidget()->sizeHint().height();
    
    env->ReleaseIntArrayElements(result, nresult, 0);
    
    Q_UNUSED(env);
    Q_UNUSED(that);
}

JNIEXPORT void JNICALL Java_ide_ccf_ccdesigner_views_embedded_SignalSlotEditorW_resizeControl(JNIEnv *env, jclass that, jlong handle, jint x, jint y, jint width, jint height)
{
    SignalSlotEditorW *obj = (SignalSlotEditorW*)handle;

    obj->parentWidget()->resize(width, height);
    obj->parentWidget()->move(x, y);
    
    Q_UNUSED(env);
    Q_UNUSED(that);
}

JNIEXPORT void JNICALL Java_ide_ccf_ccdesigner_views_embedded_SignalSlotEditorW_disposeControl(JNIEnv *env, jclass that, jlong handle)
{
    SignalSlotEditorW *obj = (SignalSlotEditorW*)handle;
    QWidget *parentW = obj->topLevelWidget();

    delete parentW;
    Q_UNUSED(env);
    Q_UNUSED(that);
}

JNIEXPORT void JNICALL Java_ide_ccf_ccdesigner_views_embedded_SignalSlotEditorW_setFont(JNIEnv *env, jclass that, jlong handle, jstring jni_family, jint size)
{
    SignalSlotEditorW *obj = (SignalSlotEditorW*)handle;
    const char *utf_family = env->GetStringUTFChars(jni_family, 0);
    QString family = QString::fromUtf8(utf_family);

    env->ReleaseStringUTFChars(jni_family, utf_family);
    
    obj->setFont(QFont(family, size));
    
    Q_UNUSED(that);
}

JNIEXPORT jstring JNICALL Java_ide_ccf_ccdesigner_views_embedded_SignalSlotEditorW_pluginFailureString(JNIEnv *env, jclass that, jlong handle)
{
    SignalSlotEditorW *obj = (SignalSlotEditorW*)handle;

    Q_UNUSED(that);

    QString res = obj->pluginFailureString();

    return env->NewStringUTF(res.toUtf8());
}

JNIEXPORT jboolean JNICALL Java_ide_ccf_ccdesigner_views_embedded_SignalSlotEditorW_initializeJambiPlugins(JNIEnv *env, jclass that, jlong handle, jstring jni_jambiBase, jstring jni_jambiPluginPath, jstring jni_customWidgetClassPath, jstring jni_resourcePath, jstring jni_jvm)
{
    SignalSlotEditorW *obj = (SignalSlotEditorW*)handle;

    Q_UNUSED(that);

    const char *utf_jambiBase = env->GetStringUTFChars(jni_jambiBase, 0);
    QString jambiBase = QString::fromUtf8(utf_jambiBase);
    env->ReleaseStringUTFChars(jni_jambiBase, utf_jambiBase);

    const char *utf_jambiPluginPath = env->GetStringUTFChars(jni_jambiPluginPath, 0);
    QString jambiPluginPath = QString::fromUtf8(utf_jambiPluginPath);
    env->ReleaseStringUTFChars(jni_jambiPluginPath, utf_jambiPluginPath);

    const char *utf_customWidgetClassPath = env->GetStringUTFChars(jni_customWidgetClassPath, 0);
    QString customWidgetClassPath = QString::fromUtf8(utf_customWidgetClassPath);
    env->ReleaseStringUTFChars(jni_customWidgetClassPath, utf_customWidgetClassPath);

    const char *utf_resourcePath = env->GetStringUTFChars(jni_resourcePath, 0);
    QString resourcePath = QString::fromUtf8(utf_resourcePath);
    env->ReleaseStringUTFChars(jni_resourcePath, utf_resourcePath);

    const char *utf_jvm = env->GetStringUTFChars(jni_jvm, 0);
    QString jvm = QString::fromUtf8(utf_jvm);
    env->ReleaseStringUTFChars(jni_jvm, utf_jvm);

    bool res = obj->initializeJambiPlugins(jambiBase, jambiPluginPath, customWidgetClassPath, resourcePath, jvm);

    Q_UNUSED(env);

    return (jboolean)res;
}

JNIEXPORT void JNICALL Java_ide_ccf_ccdesigner_views_embedded_SignalSlotEditorW_initialize(JNIEnv *env, jclass that, jlong handle)
{
    SignalSlotEditorW *obj = (SignalSlotEditorW*)handle;

    Q_UNUSED(that);

    obj->initialize();

    Q_UNUSED(env);
}

JNIEXPORT void JNICALL Java_ide_ccf_ccdesigner_views_embedded_SignalSlotEditorW_updateCustomWidgetLocation(JNIEnv *env, jclass that, jlong handle, jstring jni_path)
{
    SignalSlotEditorW *obj = (SignalSlotEditorW*)handle;

    Q_UNUSED(that);

    const char *utf_path = env->GetStringUTFChars(jni_path, 0);
    QString path = QString::fromUtf8(utf_path);

    env->ReleaseStringUTFChars(jni_path, utf_path);
    obj->updateCustomWidgetLocation(path);

    Q_UNUSED(env);
}

/**
 * 资源编辑器
 */
JNIEXPORT jlong JNICALL Java_ide_ccf_ccdesigner_views_embedded_ResourceEditorW_createControl(JNIEnv *env, jclass that, jlong parent, jlong socketWin)
{
    if (!QApplication::instance())
    {
        Display *xdisp = XOpenDisplay(0);
        (void)new QApplication(xdisp);

        #if QT_VERSION >= 0x040400
        qApp->setAttribute(Qt::AA_NativeWindows);
        #endif

        qApp->clipboard()->setProperty("useEventLoopWhenWaiting", QVariant(true));

        GtkStyle *style = gtk_widget_get_style((GtkWidget *)parent);
        GdkColor col = style->bg[GTK_STATE_NORMAL];
        QPalette qtpal(QColor(col.red>>8, col.green>>8, col.blue>>8));

        col = style->text[GTK_STATE_SELECTED];
        qtpal.setColor(QPalette::Normal, QPalette::HighlightedText, QColor(col.red>>8, col.green>>8, col.blue>>8));

        col = style->base[GTK_STATE_SELECTED];
        qtpal.setColor(QPalette::Normal, QPalette::Highlight, QColor(col.red>>8, col.green>>8, col.blue>>8));

        QApplication::setPalette(qtpal);
        QFont::insertSubstitution("Sans", "Sans Serif");
    }

    if (!envKey)
    {
        envKey = new pthread_key_t;
        pthread_key_create(envKey, NULL);
    }

    pthread_setspecific(*envKey, env);
    
    ResourceEditorW *obj = new ResourceEditorW();
    QX11EmbedWidget *client = new QX11EmbedWidget();

    obj->setParent(client);
    
    QVBoxLayout *vblayout = new QVBoxLayout(client);
    vblayout->setMargin(0);
    
    Q_UNUSED(that);

    vblayout->addWidget(obj);

    client->embedInto(socketWin);
    client->show();

    return (jlong)obj;
}

JNIEXPORT void JNICALL Java_ide_ccf_ccdesigner_views_embedded_ResourceEditorW_computeSize(JNIEnv *env, jclass that, jlong handle, jintArray result)
{
    ResourceEditorW *obj = (ResourceEditorW*)handle;
    jint *nresult = NULL;
    nresult = env->GetIntArrayElements(result, NULL);
    
    nresult[0] = obj->parentWidget()->sizeHint().width();
    nresult[1] = obj->parentWidget()->sizeHint().height();
    
    env->ReleaseIntArrayElements(result, nresult, 0);
    
    Q_UNUSED(env);
    Q_UNUSED(that);
}

JNIEXPORT void JNICALL Java_ide_ccf_ccdesigner_views_embedded_ResourceEditorW_resizeControl(JNIEnv *env, jclass that, jlong handle, jint x, jint y, jint width, jint height)
{
    ResourceEditorW *obj = (ResourceEditorW*)handle;

    obj->parentWidget()->resize(width, height);
    obj->parentWidget()->move(x, y);
    
    Q_UNUSED(env);
    Q_UNUSED(that);
}

JNIEXPORT void JNICALL Java_ide_ccf_ccdesigner_views_embedded_ResourceEditorW_disposeControl(JNIEnv *env, jclass that, jlong handle)
{
    ResourceEditorW *obj = (ResourceEditorW*)handle;
    QWidget *parentW = obj->topLevelWidget();

    delete parentW;

    Q_UNUSED(env);
    Q_UNUSED(that);
}

JNIEXPORT void JNICALL Java_ide_ccf_ccdesigner_views_embedded_ResourceEditorW_setFont(JNIEnv *env, jclass that, jlong handle, jstring jni_family, jint size)
{
    ResourceEditorW *obj = (ResourceEditorW*)handle;
    const char *utf_family = env->GetStringUTFChars(jni_family, 0);
    QString family = QString::fromUtf8(utf_family);

    env->ReleaseStringUTFChars(jni_family, utf_family);
    
    obj->setFont(QFont(family, size));
    
    Q_UNUSED(that);
}

JNIEXPORT jstring JNICALL Java_ide_ccf_ccdesigner_views_embedded_ResourceEditorW_pluginFailureString(JNIEnv *env, jclass that, jlong handle)
{
    ResourceEditorW *obj = (ResourceEditorW*)handle;

    Q_UNUSED(that);

    QString res = obj->pluginFailureString();

    return env->NewStringUTF(res.toUtf8());
}

JNIEXPORT void JNICALL Java_ide_ccf_ccdesigner_views_embedded_ResourceEditorW_updateResources(JNIEnv *env, jclass that, jlong handle, jstring jni_sourcePaths)
{
    ResourceEditorW *obj = (ResourceEditorW*)handle;

    Q_UNUSED(that);

    const char *utf_sourcePaths = env->GetStringUTFChars(jni_sourcePaths, 0);
    QString sourcePaths = QString::fromUtf8(utf_sourcePaths);

    env->ReleaseStringUTFChars(jni_sourcePaths, utf_sourcePaths);
    obj->updateResources(sourcePaths);

    Q_UNUSED(env);
}

JNIEXPORT jboolean JNICALL Java_ide_ccf_ccdesigner_views_embedded_ResourceEditorW_initializeJambiPlugins(JNIEnv *env, jclass that, jlong handle, jstring jni_jambiBase, jstring jni_jambiPluginPath, jstring jni_customWidgetClassPath, jstring jni_resourcePath, jstring jni_jvm)
{
    ResourceEditorW *obj = (ResourceEditorW*)handle;

    Q_UNUSED(that);

    const char *utf_jambiBase = env->GetStringUTFChars(jni_jambiBase, 0);
    QString jambiBase = QString::fromUtf8(utf_jambiBase);
    env->ReleaseStringUTFChars(jni_jambiBase, utf_jambiBase);

    const char *utf_jambiPluginPath = env->GetStringUTFChars(jni_jambiPluginPath, 0);
    QString jambiPluginPath = QString::fromUtf8(utf_jambiPluginPath);
    env->ReleaseStringUTFChars(jni_jambiPluginPath, utf_jambiPluginPath);

    const char *utf_customWidgetClassPath = env->GetStringUTFChars(jni_customWidgetClassPath, 0);
    QString customWidgetClassPath = QString::fromUtf8(utf_customWidgetClassPath);
    env->ReleaseStringUTFChars(jni_customWidgetClassPath, utf_customWidgetClassPath);

    const char *utf_resourcePath = env->GetStringUTFChars(jni_resourcePath, 0);
    QString resourcePath = QString::fromUtf8(utf_resourcePath);
    env->ReleaseStringUTFChars(jni_resourcePath, utf_resourcePath);

    const char *utf_jvm = env->GetStringUTFChars(jni_jvm, 0);
    QString jvm = QString::fromUtf8(utf_jvm);
    env->ReleaseStringUTFChars(jni_jvm, utf_jvm);

    bool res = obj->initializeJambiPlugins(jambiBase, jambiPluginPath, customWidgetClassPath, resourcePath, jvm);

    Q_UNUSED(env);

    return (jboolean)res;
}

JNIEXPORT void JNICALL Java_ide_ccf_ccdesigner_views_embedded_ResourceEditorW_initialize(JNIEnv *env, jclass that, jlong handle)
{
    ResourceEditorW *obj = (ResourceEditorW*)handle;

    Q_UNUSED(that);

    obj->initialize();

    Q_UNUSED(env);
}

JNIEXPORT void JNICALL Java_ide_ccf_ccdesigner_views_embedded_ResourceEditorW_updateCustomWidgetLocation(JNIEnv *env, jclass that, jlong handle, jstring jni_path)
{
    ResourceEditorW *obj = (ResourceEditorW*)handle;

    Q_UNUSED(that);

    const char *utf_path = env->GetStringUTFChars(jni_path, 0);
    QString path = QString::fromUtf8(utf_path);

    env->ReleaseStringUTFChars(jni_path, utf_path);
    obj->updateCustomWidgetLocation(path);

    Q_UNUSED(env);
}

